package com.tian.service.impl;

import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import com.tian.entity.ChargerRecord;
import com.tian.entity.PayOrder;
import com.tian.enums.PayStatusEnum;
import com.tian.enums.WxPayStatusEnum;
import com.tian.enums.WxTradeStateEnum;
import com.tian.mapper.ChargerRecordMapper;
import com.tian.mapper.PayOrderMapper;
import com.tian.service.PayOrderAsynchronousService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author tianwc  公众号：java后端技术全栈、面试专栏
 * @version 1.0.0
 * 2023年11月20日 10:00
 * 在线刷题 1200+题和1000+篇干货文章：<a href="https://woaijava.cc/">博客地址</a>
 */
@Slf4j
@Service
public class PayOrderAsynchronousServiceImpl implements PayOrderAsynchronousService {
    @Resource
    private PayOrderMapper payOrderMapper;
    @Resource
    private ChargerRecordMapper chargerRecordMapper;

    /**
     * 因为需要同时修改两个数据库表，所以这里引入事务
     *
     * @param payOrder 支付订单信息
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void processe(PayOrder payOrder) {
        //调微信 支付订单查询接口
        WxPayService wxService = new WxPayServiceImpl();
        WxPayOrderQueryResult wxPayOrderQueryResult;
        try {
            wxPayOrderQueryResult = wxService.queryOrder(payOrder.getPayOrder(), payOrder.getOrderNo());
        } catch (WxPayException e) {
            log.error("查询订单异常", e);
            return;
        }
        String tradeState = wxPayOrderQueryResult.getTradeState();
        ChargerRecord chargerRecord = chargerRecordMapper.selectByUserId(payOrder.getChargerRecordId());
        /*  交易状态.
         *   SUCCESS—支付成功,REFUND—转入退款,NOTPAY—未支付,CLOSED—已关闭,REVOKED—已撤销（刷卡支付）,USERPAYING--用户支付中,PAYERROR--支付失败(其他原因，如银行返回失败)
         */
        if (WxTradeStateEnum.CLOSED.getState().equals(tradeState) ||
                WxTradeStateEnum.NOTPAY.getState().equals(tradeState) ||
                WxTradeStateEnum.REVOKED.getState().equals(tradeState) ||
                WxTradeStateEnum.PAYERROR.getState().equals(tradeState)) {
            chargerRecord.setPayStatus(PayStatusEnum.PAY_FAILED.getPayStatus());
            //更新充电记录的支付状态为支付失败
            chargerRecordMapper.updateByPrimaryKey(chargerRecord);
            payOrder.setStatus(WxPayStatusEnum.FAILED.getStatus());
            //更新本地数据库中 支付订单状态
            payOrderMapper.updateByPrimaryKey(payOrder);
        } else if (WxTradeStateEnum.USERPAYING.getState().equals(tradeState)) {
            log.info("订单仍然处于支付中,orderNo={}", payOrder.getOrderNo());
        } else if (WxTradeStateEnum.SUCCESS.getState().equals(tradeState)) {
            chargerRecord.setPayStatus(PayStatusEnum.PAY_FINISH.getPayStatus());
            //更新充电记录的支付状态为支付成功
            chargerRecordMapper.updateByPrimaryKey(chargerRecord);
            payOrder.setStatus(WxPayStatusEnum.SUCCESS.getStatus());
            //更新本地数据库中 支付订单状态
            payOrderMapper.updateByPrimaryKey(payOrder);
        } else {
            log.error("支付状态未知：tradeState={}", tradeState);
        }
    }

    @Override
    public int countByStatus(Integer status) {
        return payOrderMapper.countByStatus(status);
    }

    @Override
    public List<PayOrder> selectByStatus(Integer status, int start, int pageSize) {
        return payOrderMapper.selectByStatus(status, start, pageSize);
    }
}
